From: svermeul@suntzu.psg.datap.ca (Stephen Vermeulen)
Message-Id: <199603151850.LAA02047@alien.psg.datap.ca>
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: Customizing custom classes, perhaps for the FAQ
X-Sun-Charset: US-ASCII
Resent-Message-Id: <"TJDle.0.J_5.GDOJn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/675
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 1281
X-Lines: 37
Status: RO

> Stefan,
>
> Do you (or anyone else) have any example code that illustrates how one goes about
> writing a MUI custom class (in particular the New function of the class) where the
> exact contents of the class are in some way customized at construction time.  For
> example you might have a fancy group containing a list, where you want the list
> to default to handling strings (the built in string construction/destruction hooks)
> but sometimes you want to use the same class to display a list which needs custom
> construct/destruct/display behaviour.
>
> Regards, Stephen

I managed to find enough of an example of almost this in the "class2.c" and psi.c example
code to piece together what to do.  Looks like what you do is at the start of
your class's new() you can do something like:

SAVEDS ULONG myclass_new(struct IClass *cl,Object *obj,Msg msg)
{

        struct TagItem *tag;

        if (tag = FindTagItem(MUIA_myclass_myattr,msg->ops_AttrList))
        {
          /* obtain your data with...
             ULONG mydata;
             mydata = tag->ti_Data;
           */
        }

        /* the "regular" DoSuperNew() follows, into this you can now
           include any data from your own tags that you picked up from
           the above code...
         */
}

Regards, Stephen



From: "Stefan Stuntz" 
Date:   Thu, 29 Feb 1996 16:36:44 +0100
X-Mailer: IntuiNews 1.3b Beta 5 (3.1.96)
Subject: Re: PSI-screens
Message-Id: <81319716@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"-FpbX3.0.UT.wqTDn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/453
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 641
X-Lines: 16
Status: RO

Sven Steiniger wrote

> My application have to be informed when the application-screen (PSI-screen)
> is opened/closed. Has anybody an idea? Stefan?
> Imagine, you change the preference with mui-prefs. MUI then close all the
> windows and then reopens it. But beetwen that PSI noticed that all windows
> on the screen are closed and close the screen. So everytime the prefs are
> changed, I have to get a new screenpointer to set the screenaspect etc.
> Currently I trigger MUI_Show in one of my customclasses but this is also
> invoked when the windowsize has changed.

Screen information is available in MUIM_Setup.

--
Greetings, Stefan


From: nsprodjt@BIX.com
Subject: Subclass List and CDDA Panel Problem
To: robv@si.hhs.nl

Subject: Creatting custom classes & attribute notification
==========================================================
>Is there any way to create custom classes which have no interface?
>(that is, are not a subclass of the Area class.)

Yeah, sure there is, write a subclass of Notify class. The only
standard methods you need are New/Dispose and Set/Get.

I started writing apps the "new" way for MUI 2 and everything in my
application is a custom class including the stuff that has no
visible interface.

From: "Stefan Stuntz" 
Date:   Thu, 07 Dec 1995 15:48:47 +0100
X-Mailer: IntuiNews 1.3b Beta 3 (5.11.95)
Subject: Re: Creatting custom classes & attribute notification
Message-Id: <64540039@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"Gbu8z3.0.Wi.-_7pm"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/46
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 281
X-Lines: 11
Status: RO

robv wrote in article <9512061459.AA21506@staring.si.hhs.nl>:

> Is there any way to create custom classes which have no interface?
> (that is, are not a subclass of the Area class.)

You can create subclasses of anything you want, starting from
root class.

--
Greetings, Stefan


From: "Stefan Stuntz" 
Date:   Thu, 07 Dec 1995 15:48:47 +0100
X-Mailer: IntuiNews 1.3b Beta 3 (5.11.95)
Subject: Re: Clipping in SubClasses
Message-Id: <64540040@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"YrAbG3.0.Fi.z_7pm"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/45
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 889
X-Lines: 26
Status: RO

Georg Kraemer wrote

> 1.) What is the correct way of clipping inside a SubClass ? Currently
> I simply set Clipping to the inner of the gadget, but this may be
> conflict with Clipping of virtual Groups for example. Of cause
> clipping is only done during the DRAW Method.

Use MUI_AddClipping()/MUI_RemoveClipping() from muimaster.library, never
use InstallClipRegion() in MUI-Windows.

> 2.) Is there a Message telling me (the Subclass) if the size of the
> gadget changes ? I need to rescale some Vektors if so. Currently I
> compare the dimensions of the gadget at the beginning of DRAW whether
> they changed or not.

MUIM_Show and MUIM_Hide.

> 3.) Whats the way to support Drag'n Drop in a SubClass ? (How can I
> build the Image for Drag with a self drawn object if it differs from
> original [Multiselect]?)

Currently, you cannot customize the D&D image.

--
Greetings, Stefan

From: "Stefan Stuntz" 
Date:   Tue, 30 Jan 1996 19:40:36 +0100
X-Mailer: IntuiNews 1.3b Beta 5 (3.1.96)
Subject: Re: Label with Text.mui
Message-Id: <81318667@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"So_Ci1.0.8D7.D5f3n"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/208
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 8476
X-Lines: 397
Status: RO

Thomas Wilhelmi wrote in article <19960130.15EFC28.10EB7@twi.rhein-main.de>:

> > Why you can't use MakeObject objects in CustomClasses?
>
> Of course I can call MakeObject in a custom-class. But I
> need a little bit of own code for disposing the Objects.
> And that's the reason why I need a custom-class even
> for labels.

Using MUI_MakeObject() is the better solution. However, if you
cannot do that because you want to make your labels & buttons
etc. with your own subclasses, heres the source of what
MUI_MakeObject() currently does.

static LONG GetControlChar(char *label)
{
        if (label)
        {
                char *c;
                if (c = strchr(label,'_'))
                        return(ToLower(*(c+1)));
        }
        return(0);
}


Object * __asm __saveds make_label(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        #define flags ((ULONG )params[1])
        Object *o;

        o = TextObject,
                MUIA_Text_Contents    , label,
                MUIA_Weight           , 0,
                MUIA_InnerLeft        , 0,
                MUIA_InnerRight       , 0,
                MUIA_FramePhantomHoriz, TRUE,
                flags & 0xff                     ? TAG_IGNORE       : MUIA_Text_HiIndex , '_',
                flags & 0xff                     ? MUIA_Text_HiChar : TAG_IGNORE        , flags & 0xff,
                flags & MUIO_Label_SingleFrame   ? MUIA_Frame       : TAG_IGNORE        , MUIV_Frame_Button,
                flags & MUIO_Label_DoubleFrame   ? MUIA_Frame       : TAG_IGNORE        , MUIV_Frame_String,
                flags & MUIO_Label_LeftAligned   ? TAG_IGNORE       : MUIA_Text_PreParse, "\33r",
                flags & MUIO_Label_Centered      ? MUIA_Text_PreParse : TAG_IGNORE      , "\33c",
                flags & MUIO_Label_FreeVert      ? MUIA_Text_SetVMax  : TAG_IGNORE      , FALSE,
                End;

        return(o);
}


Object * __asm __saveds make_button(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        Object *o;

        o = TextObject,
                ButtonFrame,
                MUIA_Text_Contents, label,
                MUIA_Text_PreParse, "\33c",
                MUIA_Text_HiIndex , '_',
                MUIA_ControlChar  , GetControlChar(label),
                MUIA_InputMode    , MUIV_InputMode_RelVerify,
                MUIA_Background   , MUII_ButtonBack,
                MUIA_Font         , MUIV_Font_Button,
                End;

        return(o);
}


Object * __asm __saveds make_checkmark(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        Object *o;

        o = ImageObject,
                ImageButtonFrame,
                MUIA_InputMode     , MUIV_InputMode_Toggle,
                MUIA_Image_Spec    , MUII_CheckMark,
                MUIA_Image_FreeVert, TRUE,
                MUIA_Background    , MUII_ButtonBack,
                MUIA_ShowSelState  , FALSE,
                MUIA_ControlChar   , GetControlChar(label),
                End;

        return(o);
}


Object * __asm __saveds make_cycle(_a0 ULONG *params)
{
        #define label   ((char *)params[0])
        #define entries ((char **)params[1])
        Object *o;

        o = CycleObject,
                MUIA_Cycle_Entries, entries,
                MUIA_ControlChar  , GetControlChar(label),
                MUIA_Font         , MUIV_Font_Button,
                End;

        return(o);
}


Object * __asm __saveds make_radio(_a0 ULONG *params)
{
        #define label   ((char *)params[0])
        #define entries ((char **)params[1])
        Object *o;

        o = RadioObject,
                label ? MUIA_Frame      : TAG_IGNORE, MUIV_Frame_Group,
                label ? MUIA_FrameTitle : TAG_IGNORE, label,
                MUIA_Radio_Entries, entries,
                MUIA_ControlChar  , GetControlChar(label),
                End;


        return(o);
}


Object * __asm __saveds make_slider(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        #define min   ((LONG  )params[1])
        #define max   ((LONG  )params[2])
        Object *o;

        o = SliderObject,
                MUIA_Slider_Min , min,
                MUIA_Slider_Max , max,
                MUIA_ControlChar, GetControlChar(label),
                End;

        return(o);
}


Object * __asm __saveds make_string(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        #define maxlen params[1]
        Object *o;

        o = StringObject,
                StringFrame,
                MUIA_ControlChar  , GetControlChar(label),
                MUIA_String_MaxLen, maxlen,
                End;

        return(o);
}


Object * __asm __saveds make_popbutton(_a0 ULONG *params)
{
        #define img ((STRPTR)params[0])
        Object *o;

        o = ImageObject,
                ImageButtonFrame,
                MUIA_Image_Spec          , img,
                MUIA_Image_FontMatchWidth, TRUE,
                MUIA_Image_FreeVert      , TRUE,
                MUIA_InputMode           , MUIV_InputMode_RelVerify,
                MUIA_Background          , MUII_BACKGROUND,
                End;

        return(o);
}


Object * __asm __saveds make_hspace(_a0 ULONG *params)
{
        #define size ((LONG)params[0])
        Object *o;

        if (size<0)
        {
                o = RectangleObject,
                        MUIA_HorizWeight, -size,
                        MUIA_VertWeight , 0,
                        End;
        }
        else
        {
                o = RectangleObject,
                        size ? MUIA_FixWidth : TAG_IGNORE, size,
                        MUIA_VertWeight, 0,
                        End;
        }

        return(o);
}


Object * __asm __saveds make_vspace(_a0 ULONG *params)
{
        #define size ((LONG)params[0])
        Object *o;

        if (size<0)
        {
                o = RectangleObject,
                        MUIA_HorizWeight, 0,
                        MUIA_VertWeight , -size,
                        End;
        }
        else
        {
                o = RectangleObject,
                        size ? MUIA_FixHeight : TAG_IGNORE, size,
                        MUIA_HorizWeight, 0,
                        End;
        }

        return(o);
}


Object * __asm __saveds make_hbar(_a0 ULONG *params)
{
        #define size params[0]
        Object *o;

        o = RectangleObject,
                MUIA_Rectangle_HBar, TRUE,
                MUIA_FixHeight     , size,
                End;

        return(o);
}


Object * __asm __saveds make_vbar(_a0 ULONG *params)
{
        #define size params[0]
        Object *o;

        o = RectangleObject,
                MUIA_Rectangle_VBar, TRUE,
                MUIA_FixWidth      , size,
                End;

        return(o);
}


Object * __asm __saveds make_menuitem(_a0 ULONG *params)
{
        #define label    ((char *)params[0])
        #define shortcut ((char *)params[1])
        #define flags    ((ULONG )params[2])
        #define data     ((ULONG )params[3])

        Object *o;

        o = MenuitemObject,
                MUIA_Menuitem_Title   , label,
                MUIA_Menuitem_Shortcut, shortcut,
                MUIA_Menuitem_Enabled , (flags & NM_ITEMDISABLED) ? FALSE : TRUE ,
                MUIA_Menuitem_Checkit , (flags & CHECKIT        ) ? TRUE  : FALSE,
                MUIA_Menuitem_Checked , (flags & CHECKED        ) ? TRUE  : FALSE,
                MUIA_Menuitem_Toggle  , (flags & MENUTOGGLE     ) ? TRUE  : FALSE,
                MUIA_UserData         , data,
                End;

        return(o);
}


Object * __asm __saveds make_menustripnm(_a0 ULONG *params)
{
        #define newmenu ((struct NewMenu *)params[0])
        #define flags  params[1]
        struct NewMenu *nm;
        Object *strip=NULL,*menu=NULL,*item=NULL,*o;

        for (nm=newmenu;nm->nm_Type!=NM_END;nm++)
                if (nm->nm_Type==NM_TITLE)
                        break;

        if (nm->nm_Type==NM_TITLE)
        {
                strip = MenustripObject,End;
                if (!strip) return(NULL);
        }

        for (nm=newmenu;nm->nm_Type!=NM_END;nm++)
        {
                if (nm->nm_Type==NM_TITLE)
                {
                        o = MenuObject,
                                MUIA_Menu_Title  , nm->nm_Label,
                                MUIA_UserData    , nm->nm_UserData,
                                MUIA_Menu_Enabled, (nm->nm_Flags & NM_MENUDISABLED) ? FALSE : TRUE,
                                End;

                        if (!o) break;
                        if (strip) DoMethod(strip,OM_ADDMEMBER,o);
                        menu = o;
                }
                else
                {
                        o = MenuitemObject,
                                MUIA_Menuitem_Title   , nm->nm_Label,
                                MUIA_Menuitem_Shortcut, (nm->nm_CommKey==NULL && (flags & MUIO_MenustripNM_CommandKeyCheck)) ? (STRPTR)MUIV_Menuitem_Shortcut_Check : nm->nm_CommKey,
                                MUIA_Menuitem_Exclude , nm->nm_MutualExclude,
                                MUIA_UserData         , nm->nm_UserData,
                                MUIA_Menuitem_Enabled , (nm->nm_Flags & NM_ITEMDISABLED) ? FALSE : TRUE ,
                                MUIA_Menuitem_Checkit , (nm->nm_Flags & CHECKIT        ) ? TRUE  : FALSE,
                                MUIA_Menuitem_Checked , (nm->nm_Flags & CHECKED        ) ? TRUE  : FALSE,
                                MUIA_Menuitem_Toggle  , (nm->nm_Flags & MENUTOGGLE     ) ? TRUE  : FALSE,
                                End;

                        if (!o) break;

                        if (nm->nm_Type==NM_ITEM)
                        {
                                if (menu) DoMethod(menu,OM_ADDMEMBER,o);
                                item = o;
                        }
                        else if (nm->nm_Type==NM_SUB)
                        {
                                DoMethod(item,OM_ADDMEMBER,o);
                        }
                }
        }

        if (nm->nm_Type!=NM_END)
        {
                if (strip)
                {
                        MUI_DisposeObject(strip);
                        return(NULL);
                }
                else if (menu)
                {
                        MUI_DisposeObject(menu);
                        return(NULL);
                }
                else if (item)
                {
                        MUI_DisposeObject(item);
                        return(NULL);
                }
        }

        return(strip ? strip : item);
}


Object * __asm __saveds make_bartitle(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        Object *o;

/*
        o = HGroup,
                Child, MUI_MakeObject(MUIO_HBar,1),
                Child, TextObject, MUIA_Text_Contents, label, MUIA_Weight, 0, End,
                Child, MUI_MakeObject(MUIO_HBar,1),
                End;
*/

        o = RectangleObject, MUIA_Rectangle_HBar, TRUE, MUIA_Rectangle_BarTitle, label, MUIA_VertWeight, 0, End;

        return(o);
}


Object * __asm __saveds make_numericbutton(_a0 ULONG *params)
{
        #define label ((char *)params[0])
        #define min   (params[1])
        #define max   (params[2])
        #define format ((char *)params[3])
        Object *o;

        o = NumericbuttonObject,
                ButtonFrame,
                MUIA_Background    , MUII_ButtonBack,
                MUIA_ControlChar   , GetControlChar(label),
                MUIA_Numeric_Min   , min,
                MUIA_Numeric_Max   , max,
                MUIA_Numeric_Format, format,
                End;

        return(o);
}

--
Greetings, Stefan

From: m.jantz@public.ndh.com (Marcel Jantz)
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: Some questions...
In-Reply-To: <65641250%agos001@pn.itnet.it>
Message-Id: <2166.6614T948T2861@public.ndh.com>
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Mailer: THOR 2.21 (Amiga;TCP/IP) *UNREGISTERED*
Lines: 54
Resent-Message-Id: <"G00zH2.0.QD2.s7B7n"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/260
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 55
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 2167


Stefano Agostinelli wrote,
>Hi,
>some questions for mui experts:
>1)What is the purpose of "what" argument in MCC_Query (or of "which"
>  in the old MCC_GetClass)? The code I've seen (UserData.c as found in
>  mui32dev) requires that it is 0, so are there other uses for it?
>2)Is it possible to make a library containing two (or more) mui public
>  classes?
>3)Is the use of OCLASS boopsi macro always allowed? And if yes,why
>  not discard INST_DATA(cl,obj) and use instead something like
>  NEWINST_DATA(obj)=INST_DATA(OCLASS(obj),obj)?

Because it maybe of some interest to use a object as member of the superclass or
the superclass' superclass etc. E.g. you may wish to use a slider as an area or
an appla as a fruit. So for some special cases it may be useful to declare the
function INST_DATA as you suggested, but it's more objectoriented correctly to
use the supplied macro.

>4)Why doesn't GetAttr return directly the requested attribute? I mean
> you have to pass it a storage pointer,why not use the return value
> for that?

Look at the psi.c example. There's a function called xget, which does exactly
what you want. I think, the reason why GetAttr works the way it does is because
you can easily give a pointer to a struct or something likely and get it filled
with the internal values/Attributes of the object. There's no way (at least
in C) to do this. In C++ you could of course use references for that.


From: Kristofer Maad 
X-Mailer: Mozilla 2.0 (X11; I; SunOS 5.5 sun4m)
Mime-Version: 1.0
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Idea: "Figure" class for 2-D drawings?
X-Url: http://sunsite.informatik.rwth-aachen.de/Listen/mui/date.html#start
Content-Transfer-Encoding: 7bit
Resent-Message-Id: <"-ktnX2.0.5T4.LLs8n"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/322
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 44
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 2001

Hi all!

I have been busy the past weeks developing a cusom class for
editing/showing B-Spline curves. Now, I was thinking that perhaps one
could extend this and make a class suitable for general 2-dimensional
drawings. It could have support for drawing lines, curves, text, etc.
and remember everything drawn so that it could redraw itself
automatically without the application needing to remember its contents.

Then I got another idea. Why not make a small class hierarchy of figure
elements? For example, if you want a diagram, the axes will get
cluttered if the window is made smaller, so the different figure
elements would better know how to redraw themselves properly. If I could
make this object-oriented, one could easily add figure elements of one's
own, just like adding classes to MUI. The main difference is that figure
elements will share the space, so that you can have a figure with both
text, curves and text in it, even overlapping. Thus, the display
environment/clipping/etc. will be completely taken care of by the (new)
Figure MUI class, so what's left is for the elements to do some
reasonable rendering based on the figure object's size, colour
preferences, etc.

Perhaps could the figure elements add "handles" that could be dragged by
the user to change the shape or other characteristics of the elements?
(My B-Spline class uses interactive dragging, and it's quite neat.)

Well, this is a lot of talk, but here's the point:

I would be happy to implement this, but I need some feedback first so
that I won't code anything that some other guy already did.

Any input appreciated!

/Kristofer

PS Perhaps somebody could make a 3-D class later on? :)

--
Name:   Kristofer Maad           | "The satisfaction in making a 'crash-
Snail:  Stureg. 12A, 3tr.        |  proof' system screw up completely
        753 14 Uppsala           |  almost makes it worthwhile."  /Kris
Phone:  018-51 11 44             |
E-Mail: m93kma@student.tdb.uu.se |   


From: "Stefan Stuntz" 
Date:   Tue, 12 Mar 1996 21:48:03 +0100
X-Mailer: IntuiNews 1.3b Beta 7 (2.2.96)
Subject: MUI Class Tree
Message-Id: <81319983@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"cLyVP3.0.iy2.eWUHn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/594
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 3678
X-Lines: 69
Status: RO

****************************************************************************
** Class Tree
****************************************************************************
**
** rootclass                    (BOOPSI's base class)
** +--Notify                   (implements notification mechanism)
** !  +--Family                (handles multiple children)
** !  !  +--Menustrip          (describes a complete menu strip)
** !  !  +--Menu               (describes a single menu)
** !  !  \--Menuitem           (describes a single menu item)
** !  +--Application           (main class for all applications)
** !  +--Window                (main class for all windows)
** !  !  \--Aboutmui           (About window of MUI preferences)
** !  +--Area                  (base class for all GUI elements)
** !     +--Rectangle          (spacing object)
** !     +--Balance            (balancing separator bar)
** !     +--Image              (image display)
** !     +--Bitmap             (draws bitmaps)
** !     !  \--Bodychunk       (makes bitmap from ILBM body chunk)
** !     +--Text               (text display)
** !     +--Gadget             (base class for intuition gadgets)
** !     !  +--String          (string gadget)
** !     !  +--Boopsi          (interface to BOOPSI gadgets)
** !     !  \--Prop            (proportional gadget)
** !     +--Gauge              (fule gauge)
** !     +--Scale              (percentage scale)
** !     +--Colorfield         (field with changeable color)
** !     +--List               (line-oriented list)
** !     !  +--Floattext       (special list with floating text)
** !     !  +--Volumelist      (special list with volumes)
** !     !  +--Scrmodelist     (special list with screen modes)
** !     !  \--Dirlist         (special list with files)
** !     +--Numeric            (base class for slider gadgets)
** !     !  +--Knob            (turning knob)
** !     !  +--Levelmeter      (level display)
** !     !  +--Numericbutton   (space saving popup slider)
** !     !  \--Slider          (traditional slider)
** !     +--Framedisplay       (private)
** !     !  \--Popframe        (private)
** !     +--Imagedisplay       (private)
** !     !  \--Popimage        (private)
** !     +--Pendisplay         (displays a pen specification)
** !     !  \--Poppen          (popup button to adjust a pen spec)
** !     +--Group              (groups other GUI elements)
** !        +--Mccprefs        (private)
** !        +--Register        (handles page groups with titles)
** !        !  \--Penadjust    (group to adjust a pen)
** !        +--Settingsgroup   (private)
** !        +--Settings        (private)
** !        +--Frameadjust     (private)
** !        +--Imageadjust     (private)
** !        +--Virtgroup       (handles virtual groups)
** !        +--Scrollgroup     (virtual groups with scrollbars)
** !        +--Scrollbar       (traditional scrollbar)
** !        +--Listview        (listview)
** !        +--Radio           (radio button)
** !        +--Cycle           (cycle gadget)
** !        +--Coloradjust     (several gadgets to adjust a color)
** !        +--Palette         (complete palette gadget)
** !        +--Popstring       (base class for popup objects)
** !           +--Popobject    (popup aynthing in a separate window)
** !           !  +--Poplist   (popup a simple listview)
** !           !  \--Popscreen (popup a list of public screens)
** !           \--Popasl       (popup an asl requester)
** +--Semaphore                (semaphore equipped objects)
**    +--Applist               (private)
**    +--Dataspace             (handles general purpose data spaces)
**       \--Configdata         (private)


From: "Stefan Stuntz" 
Date:   Sun, 18 Feb 1996 15:31:16 +0100
X-Mailer: IntuiNews 1.3b Beta 5 (3.1.96)
Subject: custom class common error
Message-Id: <81319380@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"RcVab1.0.Sw4.Dep9n"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/344
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 794
X-Lines: 31
Status: RO

Another canditate for an FAQ...

If you have a subclass of group class which internally uses
more custom classes, *never* have a dispose method like this:

ULONG dispose(...)
{
        MUI_DeleteCustomClass(data->myclass);   /******** WRONG *********/
        return(DoSuperMethodA(...));
}

Problem here is that your group class has objects created from your
custom class. These objects get deleted when the dispatcher of group
class gets the dispose method, *AFTER* your MUI_DeleteCustomClass(). It
is strictly *illegal* to delete classes with existing objects or
subclasses.

Instead, make something like this:

ULONG dispose(...)
{
        myclass = data->myclass;
        DoSuperMethodA(...);
        MUI_DeleteCustomClass(myclass);
        // *NOT* data->myclass since data is invalid here!!!
        return(0);
}

--
Greetings, Stefan


From: "Stefan Stuntz" 
Date:   Wed, 06 Mar 1996 12:51:34 +0100
X-Mailer: IntuiNews 1.3b Beta 5 (3.1.96)
Subject: Re: Area class / MUIA_Fix... Questions
Message-Id: <81319814@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"ok4wn1.0.tu1.XnNFn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/503
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 350
X-Lines: 11
Status: RO

Kai Hofmann wrote in article <60805064@informatik.uni-bremen.de>:

> But what about an attribute that will allow a fixed size for an object after
> creation time - i.e. the objects size will be calculated one time, and from
> then it can't change its size?

Write a subclass and return whatever you want during MUIM_AskMinMax.

--
Greetings, Stefan

From: "Stefan Stuntz" 
Date:   Mon, 18 Mar 1996 23:24:26 +0100
X-Mailer: IntuiNews 1.3b Beta 7 (2.2.96)
Subject: Re: 'Console' class, anyone?
Message-Id: <81320106@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"7rFri3.0.m41.lCUJn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/689
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 734
X-Lines: 18
Status: RO

Ralph Seichter wrote in article :

> That would be a nice and clean solution, if it was possible. But I think
> the console device needs to know about window border widths etc. when a new
> console is opened.

I tried to write a console.device class a few years ago when starting
with MUI but it never really worked. Console.device is really picky
concerning windows and rastports and stuff and is not well suited for an
automatic layout system such as MUI.

What might me a better idea is a subclass of areaclass that uses this
xem library stuff (see term) to display text. I havent looked at the xem
stuff yet but I doubt the interface can be worse than console.device :)

--
Greetings, Stefan



From: m.jantz@public.ndh.com (Marcel Jantz)
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: Hotkeys?
In-Reply-To: 
Message-Id: <940.6678T1166T770@public.ndh.com>
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Mailer: THOR 2.22 (Amiga;TCP/IP) *UNREGISTERED*
Lines: 35
Resent-Message-Id: <"M0oJI2.0.u86.x-fSn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1062
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 36
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 941

>I have a problem (Well I have many :): If the user click on a button
>and at the time hold down a Hotkey (Shift or something) something special
>happens. How do you test if some hotkey was pressed?

>I thougt about making a MUIM_HandleInput method and then test for
>MUIKEY_POPUP, but that semed rong somehow.

I would also use MUIM_HandleInput and listen to the Mousebuttons (by
requesting them in MUIM_Setup) and then check for Qualifiers in the
inputmsg...

>I'm sure about the right way to do this. The hotkey must be user
>configurable, but if it should be configured in the MUI prefs or in my own
>I'm not sure?

>     Hans Henrik Happe


From: "Stefan Stuntz" 
Date: 	Tue, 23 Apr 1996 21:10:06 +0100
X-Mailer: IntuiNews 1.3b Beta 7 (2.2.96)
Subject: Re: MUIKEY
Message-Id: <81321273@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"U5uKy2.0.6P6.SjIVn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1142
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 520
X-Lines: 30
Status: RO

Hi Hans!

> Wouldn't the right way of testing for MUIKEY's in the MUIM_HandleInput
> method be:
>
>     if(msg->muikey != MUIKEY_NONE)
>     {
>         switch(msg->muikey)
>         {
>             ...
>             ...
>         }
>     }
>
> instead of the way it's done in the "class3" example:
>
>     if(msg->muikey)
>     {
>         ...
>     }
>
> ???
>
> In "class3" there will be key testing for every MUIM_HandleInput call because
> MUIKEY_NONE = -1.

Stupid bug in the class3.c example.

Greetings, Stefan


From: Gilles Masson 
Message-Id: <199604251540.RAA23168@ogpsrv.unice.fr>
X-Authentication-Warning: ogpsrv.unice.fr: Host localhost didn't use HELO protocol
X-Mailer: exmh version 1.6.5 12/11/95
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: MUIM_DrawBackground local
Mime-Version: 1.0
Date: Thu, 25 Apr 96 17:40:00 +0200
X-Mts: smtp
Resent-Message-Id: <"A6AHR2.0.3S2.VsvVn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1150
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 46
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 1309

> MUIM_DrawBackground is rendering relative to the left, top variables in the
> MUIP_DrawBackground message. This gives bad rendering if you only want to
> update local parts of the background and is using a brush or even a pattern as
> background. I know MUIM_DrawBackground isn't a public method yet but maybee
> Stefan should consider a MUIM_UpdateBackground or something to do the above.

The res1 and res2 of struct MUIP_DrawBackground are the x and y offsets
for the drawn background, try it and you see how they work...
Don't know if Stefan had a good reason not to tell it  :-(


And Stefan, is there a way to change the value of MUIA_Background without
have it doing a MUI_Redraw object ?

currently to draw a MUII_ListCursor pattern in a part of my object,
i do something like that:

mDraw(...)
{
  LONG oldback;
  if (data->noredraw)
    return (0);
  DoSuperMethodA(..);
  ...
  ...
  data->noredraw = TRUE;
  get(obj,MUIA_Background,&oldback);
  set(obj,MUIA_Background,MUII_ListCursor);
  data->noredraw = FALSE;

  DoMethod(obj,MUIM_DrawBackground,...);

  data->noredraw = TRUE;
  set(obj,MUIA_Background,oldback);
  data->noredraw = FALSE;
  ...
  ...
}

So i don't do a redraw when i do the set(obj,MUIA_Background,...),
but there should be a nicer solution, isn't there ?


Gilles MASSON

From: Gilles Masson 
Message-Id: <199604251556.RAA23308@ogpsrv.unice.fr>
X-Authentication-Warning: ogpsrv.unice.fr: Host localhost didn't use HELO protocol
X-Mailer: exmh version 1.6.5 12/11/95
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: MUIA_Background problem 
In-Reply-To: Your message of "Thu, 25 Apr 96 13:18:47 +0200."
              
Mime-Version: 1.0
Date: Thu, 25 Apr 96 17:56:17 +0200
X-Mts: smtp
Resent-Message-Id: <"qCZIj1.0.6Z2._5wVn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1151
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 40
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 1423

> I`ve created a sub class "field" for a backgammon game. It`s a sub class of
> group class and represents a field of a backgammon board, e.g. a triangle
> object. The group includes 6 bodychunk objects for the stone images. So it`s
> easy to implement a drag & drop mechanism. The groups background is an image
> with the typical triangle and the bodychunk objects haven`t any background,
> so the triangle shines through. Now my problem: The group background is not
> correctly displayed, the triangle image starts not with it`s upper left
> corner. The left side of the triangle is not displayed. It looks something
> like that:

You're alllready making a custom class, so you should
set(obj,MUIA_FillArea,FALSE);
then draw yourself the background in your Draw method
with the MUIM_DrawBackground method.

#define MUIM_DrawBackground 0x804238ca /* private */ /* V11 */
struct  MUIP_DrawBackground { ULONG MethodID; LONG left; LONG top; LONG width; 
LONG height; LONG res1; LONG res2; LONG res3; }; /* private */

so something like:

DoMethod(obj,MUIM_DrawBackground,
                _mleft(obj),_mtop(obj),
                _mwidth(obj),_mheight(obj),
                x_offset,y_offset,0);

with x_offset = _mleft(obj)  or   - _mleft(obj)
 and y_offset =  _mtop(obj)  or    - _mtop(obj)

should be ok i think...



Is there a way to tell  ScrollRaster() not to clear the not scrolled
part of the area ?


Gilles MASSON


From: "Aaron Digulla" 
Date: Sun, 28 Apr 1996 14:08:03 +0100
X-Mailer: IntuiNews 1.3 (27.8.95)
Subject: Re: MUIA_Background problem 
Message-Id: <69360964@home.lake.de>
Resent-Message-Id: <"Op9hZ1.0.pk3.zSwWn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1161
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 503
X-Lines: 14
Status: RO

Gilles Masson schrieb in einer persoenlichen Nachricht ueber "Re:
MUIA_Background problem ":

> Is there a way to tell  ScrollRaster() not to clear the not scrolled
> part of the area ?

No, in that case, you must call BltBitMapRastPort() directly.

From: Gilles MASSON 
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: MUIA_Background problem 
In-Reply-To: Your message of "Sun, 28 Apr 96 14:08:03 BST."
             <69360964@home.lake.de> 
Mime-Version: 1.0
Date: Mon, 29 Apr 96 10:47:58 +0200
Sender: masson@iut-soph.unice.fr
X-Mts: smtp
Resent-Message-Id: <"0uri-3.0.B4.4C8Xn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1165
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 25
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 669

> Gilles Masson schrieb in einer persoenlichen Nachricht ueber "Re:
> MUIA_Background problem ":
> 
> > Is there a way to tell  ScrollRaster() not to clear the not scrolled
> > part of the area ?
> 
> No, in that case, you must call BltBitMapRastPort() directly.
> 

Not sure that BltBitMapRastPort() is a good idea in a MUI class...
nor if it will work with cybergraphx... ?

At the moment, i've found that:

oldbackfilhook = InstallLayerHook(_rp(obj)->Layer, LAYERS_NOBACKFILL);
ScrollRasterBF(_rp(obj),dx,dy,left,top,right,bottom);
InstallLayerHook(_rp(obj)->Layer, oldbackfilhook);

LAYERS_NOBACKFILL tells ScrollRasterBF to not fill the area...



Gilles MASSON


From: Jason S Birch 
Message-Id: <199604291023.SAA08262@decadence>
Subject: Custom classes made easy
To: mui@sunsite.Informatik.RWTH-Aachen.DE (MUI ML)
Date: Mon, 29 Apr 1996 18:23:10 +0800 (WST)
X-Mailer: ELM [version 2.4 PL25]
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
Resent-Message-Id: <"huLEY2.0.Xi.xa9Xn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1166
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 298
Status: RO
Content-Type: text/plain; charset="US-ASCII"
Content-Length: 8396

Hi all. A few days ago I was thinking about the tedium of the
housekeeping required when creating a custom class (keeping track of
methods and attributes you've created, assigning them non-overlapping
numbers, making sure you don't forget any in the dispatcher, etc) and
decided to try and make it simpler. Inspired by VisualC++'s technique
of using the preprocessor, I had a look at that but being more
ambitious than Microsoft I quickly realized I wasn't going to be able
to do one of the more fundamental things, which was automatically keep
track of what methods and attributes had been defined and generate the
dispatcher and ID's appropriately.

So, I set out to learn flex and have come up with a preprocessor I
called mui2c. It has a fairly simple syntax, and can turn something
like this:

-------------------------

Class ( Robot :: MUIC_Area )

/* Some comment on
    the class */

This can be anything at all.

Data ( instancedata )

struct {
        long a;
        long b;
} instancedata;

Method ( OM_NEW )
{
        some stuff  {
            some more stuff
        }
}

    Method(MUIM_Robot_Test)
    {
        testing...
    }
/*
Method(MUIM_Robot_Commented)
{
    This will be ignored.
}
*/

// Method(MUIM_Robot_C++Commented)
// {
//      So will this.
// }

Method  ( OM_GET  )
{
    Attribute(MUIA_Robot_TestAttribute):public
        *store = data->a; return(TRUE);
    Attribute(MUIA_Robot_TestPrivAtt)
        *store = data->b; return(TRUE);
}

Method(OM_SET)
{
    Attribute(MUIA_Robot_TestPrivAtt)
        b = tag->ti_Data;   break;
    Attribute(MUIA_Robot_TestAttribute):public
        a = tag->ti_Data;   break;
}
-------------------------

into this:

-------------------------

/*
 * Implementation file for class Robot.
 * Automatically generated on Mon Apr 29 17:32:22 1996
 *
 */


#include "test2.h"
#include "test2p.h"
/* Some comment on
    the class */

This can be anything at all.

struct {
        long a;
        long b;
} instancedata;

static SAVEDS ULONG Robot_OM_NEW(struct IClass *cl, Object *obj, Msg msg)
{
        some stuff  {
            some more stuff
        }
}


static SAVEDS ULONG Robot_MUIM_Robot_Test(struct IClass *cl, Object *obj, Msg msg)
{
        testing...
}

/*
Method(MUIM_Robot_Commented)
{
    This will be ignored.
}
*/

// Method(MUIM_Robot_C++Commented)
// {
//      So will this.
// }

static SAVEDS ULONG Robot_OM_GET(struct IClass *cl, Object *obj, Msg msg)
{
   struct instancedata *data = INST_DATA(cl, obj);
   ULONG *store = ((struct opGet *) msg)->opg_Storage;
   ULONG tag = ((struct opGet *) msg)->opg_AttrID;

   switch (tag) {
        case MUIA_Robot_TestAttribute:
        *store = data->a; return(TRUE);
        case MUIA_Robot_TestPrivAtt:
        *store = data->b; return(TRUE);
   }
   return (DoSuperMethodA(cl, obj, msg));
}


static SAVEDS ULONG Robot_OM_SET(struct IClass *cl, Object *obj, Msg msg)
{
   struct instancedata *data = INST_DATA(cl, obj);
   struct TagItem *tags, *tag;

   for (tags = ((struct opSet *) msg)->ops_AttrList; tag = NextTagItem(&tags);) {
      switch (tag) {
        case MUIA_Robot_TestPrivAtt:
        b = tag->ti_Data;   break;
        case MUIA_Robot_TestAttribute:
        a = tag->ti_Data;   break;
      }
   }
  return (DoSuperMethodA(cl, obj, msg));
}

static SAVEDS ASM ULONG Robot_Dispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
{
   switch (msg->MethodID) {
     case OM_NEW: return (Robot_OM_NEW(cl, obj, (APTR) msg));
     case MUIM_Robot_Test: return (Robot_MUIM_Robot_Test(cl, obj, (APTR) msg));
     case OM_GET: return (Robot_OM_GET(cl, obj, (APTR) msg));
     case OM_SET: return (Robot_OM_SET(cl, obj, (APTR) msg));
   }

   return (DoSuperMethodA(cl, obj, msg));
}

struct MUI_CustomClass *Robot_Create(void)
{
   return (MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct instancedata), RobotDispatcher));
}
-------------------------

plus a couple of header files, one with public tags in it:

/*
 * Header file for class Robot.
 * Automatically generated on Mon Apr 29 17:32:22 1996
 *
 */

struct MUI_CustomClass *Robot_Create(void);

/* PUBLIC METHODS */


/* PUBLIC ATTRIBUTES */
#define MUIA_Robot_TestAttribute		0x1b5f0001

and one with private tags:

/*
 * Private header file for class Robot.
 * Automatically generated on Mon Apr 29 17:32:22 1996
 *
 */



/* PRIVATE METHODS */
#define MUIM_Robot_Test		0x1b5f0000


/* PRIVATE ATTRIBUTES */
#define MUIA_Robot_TestPrivAtt		0x1b5f0002

-----------------------

Ok, now, after having done this, I have a few questions I'd like to
ask of people who might be interested in a (free) program like this.
First, what do you think of the syntax? Currently it looks like this:

Class(Classname::Superclass)
Data(InstanceDataName)

Method(SomeMethodName)[:public]
...
Method(OM_GET)
{
   Attribute(SomeAttributeName)[:public]
   [...] return(TRUE);
}
...
Method(OM_SET)
{
   Attribute(SomeAttributeName)[:public]
   [...] break;
}
...

etc. Personally, I'm not too keen on the syntax (it seemed like a good
idea at the time, but after actually trying it out it looks a bit
funny) so I'm open to suggestions. Currently it is fairly resilient --
the odd spacings I placed in the test file were to illustrate what
matters and what doesn't. I'd also like to know how people would like
to indicate the base tag value to generate the rest from -- somehow a
"BaseValue(nnn)" doesn't seem right, but if people don't care then I
can do something like that.

As you might have guessed, attributes may only be specified within an
OM_GET or an OM_SET method. Currently, if someone declares one
definition (eg. in OM_GET) to be public and the other to not, it
simply generates the tag in the public file and doesn't do anything
fancy to stop external users. All other methods just use a standard
header. An alternative syntax for attributes might be something like:

Attribute(SomeAttribute)
{
	Get: {blah}
	Set: {blah}
}

and let the OM_GET and OM_SET methods be generated accordingly.

Normal source code (and comments -- it understands nested comments,
too) can be included anywhere and will simply be copied through, so if
you want to do any fancy tricks that should be ok. Also, within a
Method(){..}, you'll always have at least "cl", "obj", and "msg"
available (much like "this" in C++) with perhaps "data" as well.
Additionally, within an OM_GET and OM_SET there are a few others.
Would you prefer not to have these automatically available? Would
you prefer different names?

A limitation I enforced (which can be removed if I use { and } to
delimit the class) is there can be only one class definition per file.
I also made all function definitions static to ensure no accidental
name clashes, although with the class name prepended this is unlikely.
It does add security, though.

A trick I used to work out which methods and attributes should have
tags given without having to search through all the include files and
see what was already defined was to decide that only tags starting
with MUIM__ and MUIA__ should be considered
belonging to the class, and everything else is assumed to be defined
elsewhere (eg. OM_GET).

The actual code generated is simply taken from a big list of strings.
Provided another language has a similar structure, I see no reason why
eg. E or Modula strings couldn't be used instead to output the code in
the language of choice. If someone wanted to support this, then I can
make the program read the strings from a seperate file, or build them
in and make the selection a commandline option. Also, if someone has
better strings than mine, let me know. :-)

That'll do for now. If you want to try it out, grab the file
http://www.cs.uwa.edu.au/~jasonb/mui2c.lha. Mail me (or the list) any
comments, suggestions, or criticisms you might have. This is more a
proof-of-concept than a finished idea, so there's plenty of room for
improvement. I just want to get a little feedback on what people want
(if anything) before I spend too much more time on this.

The lha archive is 19k, the executeable is about 35k.

Cheers,
Jason.

-- 
Jason S Birch                        ,-_|\ email: jasonb@cs.uwa.edu.au
Department of Computer Science      /     \ Tel (work): +61 9 380 1840
The University of Western Australia *_.-._/ Fax (work): +61 9 380 1089
Nedlands  W. Australia  6907             v  Tel (home): +61 9 386 8630

From: McBoe@abyss.apl.s.shuttle.de (Jens Boenisch)
Subject: Re: MUIA_Background problem
Message-Id: <227912f5.u7t157e.8d9a4-McBoe@abyss.apl.s.shuttle.de>
Date: Mon, 29 Apr 1996 23:34:00 GMT
Resent-Message-Id: <"9_AgU2.0.Bl4.blNXn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1173
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 803
X-Lines: 30
Status: RO

Hi Gilles (Gilles MASSON), in <199604290848.KAA06110@ogpsrv.unice.fr> on Apr 29 you wrote:

> Not sure that BltBitMapRastPort() is a good idea in a MUI class...

Indeed. ClipBlit is a better one.

> nor if it will work with cybergraphx... ?

It will, like every other Function of graphics.library, work.

> At the moment, i've found that:
> 
> oldbackfilhook = InstallLayerHook(_rp(obj)->Layer, LAYERS_NOBACKFILL);
> ScrollRasterBF(_rp(obj),dx,dy,left,top,right,bottom);
> InstallLayerHook(_rp(obj)->Layer, oldbackfilhook);

Mh, sounds crazy :)

The suggested code for fast scrolling without clearing the old area looks
like this:

ClipBlit(_rp(obj),...);
oldMask = SetWriteMask (_rp(obj), 0);
ScrollRaster (_rp(obj),dx,dy,left,top,right,bottom);
SetWriteMask (_rp(obj), oldMask);

So short ...

	Jens

From: Gilles MASSON 
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Subject: Re: MUIA_Background problem 
In-Reply-To: Your message of "Mon, 29 Apr 96 23:34:00 GMT."
             <227912f5.u7t157e.8d9a4-McBoe@abyss.apl.s.shuttle.de> 
Mime-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Date: Thu, 02 May 96 18:56:01 +0200
Sender: masson@iut-soph.unice.fr
X-Mts: smtp
Resent-Message-Id: <"ScoMs2.0.Dg5.KdEYn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1195
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 37
Status: RO
Content-Type: text/plain; charset="iso-8859-1"
Content-Length: 909

> > oldbackfillhook =3D InstallLayerHook(_rp(obj)->Layer, LAYERS_NOBACKFI=
LL);
> > ScrollRasterBF(_rp(obj),dx,dy,left,top,right,bottom);
> > InstallLayerHook(_rp(obj)->Layer, oldbackfillhook);
> =

> Mh, sounds crazy :)
> =

> The suggested code for fast scrolling without clearing the old area loo=
ks
> like this:
> =

> ClipBlit(_rp(obj),...);

works ok, but don't seem to be quicker than my ScrollRasterBF,
(i tested with AGA and CGFX). =

I think the only change is the time used by the InstallLayerHook(),
which should be short.

> oldMask =3D SetWriteMask (_rp(obj), 0);
> ScrollRaster (_rp(obj),dx,dy,left,top,right,bottom);
> SetWriteMask (_rp(obj), oldMask);

This one don't scroll anything !


A good way could be to do a good SetWriteMask() for the chipset,
but it's no good with user defined mui backgrounds ! (can't know
which bitplanes are really used) So it's not good  :-(


Gilles MASSON

From: McBoe@abyss.apl.s.shuttle.de (Jens Boenisch)
Subject: Re: MUIA_Background problem
Message-Id: <227d8a96.u7t157e.9c42-McBoe@abyss.apl.s.shuttle.de>
Date: Fri, 03 May 1996 08:53:00 GMT
Resent-Message-Id: <"VyTB12.0.sw4.I_YYn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1198
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 1134
X-Lines: 34
Status: RO

Hi Gilles (Gilles MASSON), in <199605021656.SAA23463@ogpsrv.unice.fr> on May 02 you wrote:

> > ClipBlit(_rp(obj),...);
> 
> works ok, but don't seem to be quicker than my ScrollRasterBF,
> (i tested with AGA and CGFX). 
> I think the only change is the time used by the InstallLayerHook(),
> which should be short.

I haven't tested it, but if this takes the same amount of time
like InstallClipRegion() it is rather expensive ...

Another advantage of my code is, that it works with OS2 too.

> > oldMask = SetWriteMask (_rp(obj), 0);
> > ScrollRaster (_rp(obj),dx,dy,left,top,right,bottom);
> > SetWriteMask (_rp(obj), oldMask);
> 
> This one don't scroll anything !

Of course doesn't it scroll any Bitplanes but it scrolls the damage regions
and this is the only intention of this three lines.

> A good way could be to do a good SetWriteMask() for the chipset,
> but it's no good with user defined mui backgrounds ! (can't know
> which bitplanes are really used) So it's not good  :-(

When you know, what you are doing a WriteMask (rp, 0) can be a good
idea. And in the above example it *is* a good idea.

So short ...

	Jens

From: "Stefan Stuntz" 
Date: 	Sat, 11 May 1996 11:28:13 +0100
X-Mailer: IntuiNews 1.3b Beta 7 (2.2.96)
Subject: Re: drawing Bitmap and Bodychunk in rastport ?
Message-Id: <81322055@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"5MCNi3.0.O21.yt5bn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1265
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 351
X-Lines: 12
Status: RO

Gilles MASSON wrote in article <199605091536.RAA22282@ogpsrv.unice.fr>:

> How could i draw in my custom class rastport some image
> of Bitmap object or Bodychunk object, like it's done
> in MUI_List with MUIM_List_CreateImage ?

Make your class subclass of group class, use a custom layout hook and
place Bitmap objects there.

--
Greetings, Stefan


Subject: MCP MCC_GetClass() function ?
Mime-Version: 1.0
Date: Mon, 20 May 96 13:54:42 +0200
Sender: masson@iut-soph.unice.fr
X-Mts: smtp
Resent-Message-Id: <"0j-oR.0.sD.ku5en"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1368
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 22
Status: RO
Content-Type: text/plain; charset="us-ascii"
Content-Length: 613


My mcc and mcp code work, but i have some questions with
MCC_GetClass()/MCC_Query() function. (i've seen both names).

my tests with existing mcc/mcp (Busy,Listtree...) and kmel mcc
example source show me that :

For MCC class:
MCC_Query(0)  return the mcc class ptr... ok.
MCC_Query(1) and MCC_Query(2) return 0, ok.
MCC_Query(3)  return 1... *** WHY ??? ***

For MCP class:
MCC_Query(0)  return a class ptr... *** WHICH ONE and WHY ??? ***
MCC_Query(1)  return the mcp class ptr... ok.
MCC_Query(2)  return NULL or a Bitmap/Bodychunk object ptr, ok.
MCC_Query(3)  return 0... *** WHY ??? ***


Gilles MASSON

Subject: Re: public mcc...[ libnix libinit.c ]
Resent-Message-Id: <"udXdc2.0.HY4.x5Ven"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1371
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 1358
X-Lines: 39
Status: RO

Hello all,

On 21-May-96, Gilles MASSON wrote:

> > I did the MCC UserData Example with gcc. I have used the library code of
> > the libnix-package. The only real Problem was the register a4. (Dataspace)
> > 
> Anyway, i have done changes to libinit.c and mccheader.c (from kmel)
> and succeed to make a non baserel stuff for mcc/mcp with gcc, so you
> don't have to deal with a4 and it's easier (code is bigger and slower
> anyway of course) and it's work well.
> you can get it on ftp://bibliut.unice.fr/amiga/mui/gcc_mcc10.lha
> 
I have also written an adapted version of libinit.c with these features:

- baserelative
- __UserLibOpen/Close() calls
- global dataspace available in Open/Close
- multithreading allowed in Open/Close(), i.e. I can do DOS I/O, or
  even spawn a library thread that shares the global data space.
- semaphore and protected by fake opener.

I'm now adapting it for a device frontend, datatype frontend, and maybe
the MUI stuff, although I need some input on the latter.

I will put it on my homepage as "dd_libinit.c" - sources and stuff included.

http://www.stack.urc.tue.nl/~leon/

Should be available when you read this.

Regards,
--
Leon `LikeWise' Woestenberg  
Information Technology Science student, Eindhoven University of Technology.

Subject: Re: public mcc...[ libnix libinit.c ]
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Date: Wed, 22 May 1996 17:09:07 +0200 (MET DST)
In-Reply-To: <199605221407.QAA10192@ogpsrv.unice.fr> from "Gilles MASSON" at May 22, 96 04:07:01 pm
X-Mailer: ELM [version 2.4 PL24]
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
Resent-Message-Id: <"fMU2P.0.By5.cuoen"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1377
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 22
Status: RO
Content-Type: text/plain; charset="US-ASCII"
Content-Length: 690


Hello all,
> 
> > I'm now adapting it for a device frontend, datatype frontend, and maybe
> > the MUI stuff, although I need some input on the latter.
> 
> Is it really intersting to make MCC/MCP baserelative ?
>
No. The dd_libinit.c was not especially written for MCC/MCP; it was more
an alternative to the rather simple libnix libinit.c, which didn't support
Open/Close() at all. 

I'm not familiar with programming public classes for MUI, but I'm very much
interested in writing a libinit.c skeleton for it.

> They should have very few global datas and a4 seems to be a
> problematic stuff which is little used in fact.
>
What is the problematic item regarding a4?
 
Greetings, Leon.


Subject: RE: re: mcc ... [libnix libinit.c]
Message-Id: <960522201849_101526.3324_IHK86-1@CompuServe.COM>
Resent-Message-Id: <"Feo4D2.0.-w.1Uten"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1383
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 1441
X-Lines: 34
Status: RO

> Hello all,
> > 
> > > I'm now adapting it for a device frontend, datatype frontend, and maybe
> > > the MUI stuff, although I need some input on the latter.
> > 
> > Is it really intersting to make MCC/MCP baserelative ?
> >
> No. The dd_libinit.c was not especially written for MCC/MCP; it was more
> an alternative to the rather simple libnix libinit.c, which didn't support
> Open/Close() at all. 
> 
> I'm not familiar with programming public classes for MUI, but I'm very much
> interested in writing a libinit.c skeleton for it.
>
It is rather simple to program a public MUI class. Look at the example in the
developers package.
A skeleton for a public MUI class is a very good idea. (I had already the same
in my mind, but I think I have no time to do it.) Let me explain my idea of
this task:
- I don't think that there is a need for Open/Close in public MUI classes.
- The only thing the skeleton should do is, Open muimaster.library and making
  MUIMasterBase, UtilityBase, DOSBase and IntuitionBase globally visible.
  (there is the need for a4, if baserel). Functions from these Libraries are
  usually called in MUI classes.
- the skeleton should only take reference to the dispatcher function and struct
  data.
- the library code could be kept really simple. probably in assembler. maybe
  below 100 bytes??



Willi Burkhardt 				  101526.3324@compuserve.com
		      -------> I will have a new address in a few weeks ....

Subject: RE: re: mcc ... [libnix libinit.c]
Resent-Message-Id: <"puFHJ.0.Zo4.DDjfn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1399
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 2347
X-Lines: 53
Status: RO

Hi all,

On 23-May-96, Willi wrote:

> > an alternative to the rather simple libnix libinit.c, which didn't support
> > Open/Close() at all. 
> > 
> > I'm not familiar with programming public classes for MUI, but I'm very much
> > interested in writing a libinit.c skeleton for it.
> >
> It is rather simple to program a public MUI class. Look at the example in the
> developers package.
> A skeleton for a public MUI class is a very good idea. (I had already the same
> in my mind, but I think I have no time to do it.) Let me explain my idea of
> this task:
> - I don't think that there is a need for Open/Close in public MUI classes.
> - The only thing the skeleton should do is, Open muimaster.library and making
>   MUIMasterBase, UtilityBase, DOSBase and IntuitionBase globally visible.
>   (there is the need for a4, if baserel). Functions from these Libraries are
>   usually called in MUI classes.
>
"Opening muimaster.library" does implicitly need Open/Close, as it breaks
single-threading. (It does DOS file I/O, and Wait()s). This means the
muimaster.library must be opened in Open(), but only once, i.e. when the
usercount goes from 0 to 1. There is confusion whether ramlib is able
to sequentialize everything ok. (page 65, The Amiga Guru Book). I think
I'll ask again at c.s.a.programmer, but last time I did, a discussion
broke lose, among advanced programmers, even some that are developing
the next AmigaOS right now...

> - the skeleton should only take reference to the dispatcher function and struct
>   data.
Yes, that's right. It must only make things easier for the programmer,
but not must limit the class' capabilities by restrictions.

> - the library code could be kept really simple. probably in assembler. maybe
>   below 100 bytes??
> 
I have a library skeleton that has the same protection scheme as the
adapted libinit.c. However, it doesn't set up C specific stuff such as
a4 global data pointers. It was 300 to 400 bytes. The libnix adapted
skeleton is 900 bytes. IMHO, we should stick with the C source for a
while, until we get the skeleton worked out. A conversion into assembler
is always possible later.

Regards,
--
Leon `LikeWise' Woestenberg  
Information Technology Science student, Eindhoven University of Technology.

Subject: custom class skeleton
Message-Id: <81322388@magic.informatik.tu-muenchen.de>
Organization: Home of MUI
Resent-Message-Id: <"pNl113.0.Ue4.f-tgn"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1422
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
Content-Type: text
Content-Length: 9571
X-Lines: 432
Status: RO

Hi!

Following the recent discussions about library skeletons, I use one
completely written in C for all my MUI classes. I plan to clean up,
document and release it some day. If you are willing to try it now
without comments and docs, here we go. You need to define a few things
like CLASS and SUPERCLASS and your Data structure and then include the
module before any other code. Well, I'm sure you'll find out what to
do...


/* mccheader.c */

#include 
#include 
#include 
#include 
#include 

#include 

#include 
#include 

static const char UserLibName[] = CLASS;

struct Library *MUIClassBase;
struct Library *MUIMasterBase;
struct Library *MUIGfxBase;
struct Library *MUILowLevelBase;
struct Library *SysBase;
struct Library *UtilityBase;
struct Library *DOSBase;
struct Library *GfxBase;
struct Library *IntuitionBase;

#ifdef SUPERCLASS
struct MUI_CustomClass *ThisClass;
#endif

#ifdef SUPERCLASSP
struct MUI_CustomClass *ThisClassP;
#endif


#ifdef _DCC

#define REG(x) __ ## x
#define ASM
#define SAVEDS __geta4

#else

#define REG(x) register __ ## x
#define ASM    __asm
#define SAVEDS __saveds

#endif



/******************************************************************************/
/* External references                                                        */
/******************************************************************************/

BOOL ASM UserLibInit   (REG(a6) struct Library *base);
BOOL ASM UserLibExpunge(REG(a6) struct Library *base);
BOOL ASM UserLibOpen   (REG(a6) struct Library *base);
BOOL ASM UserLibClose  (REG(a6) struct Library *base);

extern void kprintf(const char *, ...);


/******************************************************************************/
/* Structures                                                                 */
/******************************************************************************/

struct LibraryHeader
{
	struct Library         lh_Library;
	BPTR                   lh_Segment;
	struct SignalSemaphore lh_Semaphore;
};

struct LibraryHeader * ASM LibInit   (REG(a0) BPTR Segment);
BPTR                   ASM LibExpunge(REG(a6) struct LibraryHeader *base);
struct LibraryHeader * ASM LibOpen   (REG(a6) struct LibraryHeader *base);
BPTR                   ASM LibClose  (REG(a6) struct LibraryHeader *base);
LONG                   ASM LibNull   (VOID);
ULONG           SAVEDS ASM MCC_Query (REG(d0) LONG which);

static const APTR LibVectors[] =
{
	LibOpen,
	LibClose,
	LibExpunge,
	LibNull,
	MCC_Query,
	(APTR)-1
};



/******************************************************************************/
/* Dummy entry point and LibNull() function all in one                        */
/******************************************************************************/

LONG ASM LibNull(VOID)
{
	return(NULL);
}


static const struct Resident ROMTag =
{
	RTC_MATCHWORD,
	&ROMTag,
	&ROMTag + 1,
	0,
	VERSION,
	NT_LIBRARY,
	0,
	UserLibName,
	UserLibID,
	LibInit
};

#ifdef MYDEBUG
#define LIBHEADER
#include "debug.c"
#endif



/******************************************************************************/
/* Standard Library Functions, all of them are called in Forbid() state.      */
/******************************************************************************/

struct LibraryHeader * ASM SAVEDS LibInit(REG(a0) BPTR Segment)
{
	struct LibraryHeader *base;

	SysBase = *((struct Library **)4);

	D(DBF_LIB,bug("start...\n"));

	#ifdef __SASC
	#ifdef _M68040
	if (!(((struct ExecBase *)SysBase)->AttnFlags & AFF_68040))
		return(NULL);
	#endif
	#ifdef _M68030
	if (!(((struct ExecBase *)SysBase)->AttnFlags & AFF_68030))
		return(NULL);
	#endif
	#ifdef _M68020
	if (!(((struct ExecBase *)SysBase)->AttnFlags & AFF_68020))
		return(NULL);
	#endif
	#endif

	if (base = (struct LibraryHeader *)MakeLibrary((APTR)LibVectors,NULL,NULL,sizeof(struct LibraryHeader),NULL))
	{
		base->lh_Library.lib_Node.ln_Type = NT_LIBRARY;
		base->lh_Library.lib_Node.ln_Name = (char *)UserLibName;
		base->lh_Library.lib_Flags        = LIBF_CHANGED | LIBF_SUMUSED;
		base->lh_Library.lib_Version      = VERSION;
		base->lh_Library.lib_Revision     = REVISION;
		base->lh_Library.lib_IdString     = (char *)UserLibID;

		base->lh_Segment  = Segment;

		InitSemaphore(&base->lh_Semaphore);

		AddLibrary((struct Library *)base);
	}
	else
	{
		D(DBF_LIB,bug("\7MakeLibrary() failed\n"));
	}

	return(base);
}


BPTR ASM SAVEDS LibExpunge(REG(a6) struct LibraryHeader *base)
{
	struct Library *SysBase = *((struct Library **)4);
	BPTR rc;

	D(DBF_LIB,bug("OpenCount=%ld\n",base->lh_Library.lib_OpenCnt));

	if (base->lh_Library.lib_OpenCnt)
	{
		base->lh_Library.lib_Flags |= LIBF_DELEXP;
		D(DBF_LIB,bug("Setting LIBF_DELEXP\n"));
		return(NULL);
	}

	Remove((struct Node *)base);
	rc = base->lh_Segment;
	FreeMem((BYTE *)base - base->lh_Library.lib_NegSize,base->lh_Library.lib_NegSize + base->lh_Library.lib_PosSize);

	return(rc);
}


struct LibraryHeader * ASM SAVEDS LibOpen(REG(a6) struct LibraryHeader *base)
{
	struct Library *SysBase = *((struct Library **)4);
	struct LibraryHeader *rc;

	base->lh_Library.lib_OpenCnt++;
	base->lh_Library.lib_Flags &= ~LIBF_DELEXP;

	D(DBF_LIB,bug("OpenCount=%ld\n",base->lh_Library.lib_OpenCnt));

	ObtainSemaphore(&base->lh_Semaphore);

	if (UserLibOpen((struct Library *)base))
	{
		rc = base;
	}
	else
	{
		rc = NULL;
		base->lh_Library.lib_OpenCnt--;
		D(DBF_LIB,bug("\7UserLibOpen() failed\n"));
	}

	ReleaseSemaphore(&base->lh_Semaphore);

	return(rc);
}


BPTR ASM SAVEDS LibClose(REG(a6) struct LibraryHeader *base)
{
	struct Library *SysBase = *((struct Library **)4);
	BPTR rc = NULL;

	D(DBF_LIB,bug("OpenCount=%ld %s\n",base->lh_Library.lib_OpenCnt,base->lh_Library.lib_OpenCnt==0 ? "\7ERROR" : ""));

	ObtainSemaphore(&base->lh_Semaphore);
	UserLibClose((struct Library *)base);
	ReleaseSemaphore(&base->lh_Semaphore);

	if (--base->lh_Library.lib_OpenCnt == 0)
	{
		if (base->lh_Library.lib_Flags & LIBF_DELEXP)
		{
			rc = LibExpunge(base);
		}
	}

	return(rc);
}






BOOL ASM SAVEDS UserLibOpen(REG(a6) struct Library *base)
{
	ULONG ASM _Dispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
	ULONG ASM _DispatcherP(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg);
	BOOL ClassInitFunc(struct Library *base);

	D(DBF_CLASS,bug("%ld\n",base->lib_OpenCnt));

	if (base->lib_OpenCnt==1)
	{
		if (MUIMasterBase = OpenLibrary("muimaster.library",libversion(base)))
		{
			if (MUIGfxBase = OpenLibrary("muigfx.library",libversion(base)))
			{
				if (MUILowLevelBase = OpenLibrary("muilowlevel.library",libversion(base)))
				{
					#ifdef SUPERCLASS
					if (ThisClass = MUI_CreateCustomClass(base,SUPERCLASS,NULL,sizeof(struct Data),_Dispatcher))
					#endif
					{
						BOOL res;

						#ifdef SUPERCLASSP
						ThisClassP = MUI_CreateCustomClass(base,SUPERCLASSP,NULL,sizeof(struct DataP),_DispatcherP);
						#endif

						#ifdef SUPERCLASS
						UtilityBase   = ThisClass->mcc_UtilityBase;
						DOSBase       = ThisClass->mcc_DOSBase;
						GfxBase       = ThisClass->mcc_GfxBase;
						IntuitionBase = ThisClass->mcc_IntuitionBase;
						#else
						UtilityBase   = ThisClassP->mcc_UtilityBase;
						DOSBase       = ThisClassP->mcc_DOSBase;
						GfxBase       = ThisClassP->mcc_GfxBase;
						IntuitionBase = ThisClassP->mcc_IntuitionBase;
						#endif

						#ifdef ClassInit
						res = ClassInitFunc(base);
						#else
						res = TRUE;
						#endif

						if (res)
						{
							return(TRUE);
						}

						#ifdef SUPERCLASSP
						if (ThisClassP)
							MUI_DeleteCustomClass(ThisClassP);
						#endif

						#ifdef SUPERCLASS
						MUI_DeleteCustomClass(ThisClass);
						#endif
					}
					CloseLibrary(MUILowLevelBase);
				}
				CloseLibrary(MUIGfxBase);
			}
			CloseLibrary(MUIMasterBase);
		}
		D(DBF_CLASS,bug("fail.: %08lx %s\n",base,base->lib_Node.ln_Name));

		#ifdef SUPERCLASS
		ThisClass     = NULL;
		#endif

		#ifdef SUPERCLASSP
		ThisClassP    = NULL;
		#endif

		MUIMasterBase = NULL;
		MUIGfxBase    = NULL;
		UtilityBase   = NULL;
		DOSBase       = NULL;
		GfxBase       = NULL;
		IntuitionBase = NULL;

		return(FALSE);
	}
	return(TRUE);
}


BOOL ASM SAVEDS UserLibClose(REG(a6) struct Library *base)
{
	VOID ClassExitFunc(struct Library *base);

	D(DBF_CLASS,bug("%ld\n",base->lib_OpenCnt));

	if (base->lib_OpenCnt==1)
	{
		#ifdef ClassExit
		ClassExitFunc(base);
		#endif

		#ifdef SUPERCLASSP
		if (ThisClassP)
			MUI_DeleteCustomClass(ThisClassP);
		#endif

		#ifdef SUPERCLASS
		if (ThisClass)
			MUI_DeleteCustomClass(ThisClass);
		#endif

		if (MUILowLevelBase)
			CloseLibrary(MUILowLevelBase);

		if (MUIGfxBase)
			CloseLibrary(MUIGfxBase);

		if (MUIMasterBase)
			CloseLibrary(MUIMasterBase);

		#ifdef SUPERCLASS
		ThisClass       = NULL;
		#endif

		#ifdef SUPERCLASSP
		ThisClassP      = NULL;
		#endif

		MUILowLevelBase = NULL;
		MUIMasterBase   = NULL;
		MUIGfxBase      = NULL;

		UtilityBase     = NULL;
		DOSBase         = NULL;
		GfxBase         = NULL;
		IntuitionBase   = NULL;
	}
	return(TRUE);
}


ULONG SAVEDS ASM MCC_Query(REG(d0) LONG which)
{
	switch (which)
	{
		#ifdef SUPERCLASS
		case 0: return((ULONG)ThisClass);
		#endif

		#ifdef SUPERCLASSP
		case 1: return((ULONG)ThisClassP);
		#endif

		#ifdef PREFSIMAGEOBJECT
		case 2:
		{
			Object *obj = PREFSIMAGEOBJECT;
			return((ULONG)obj);
		}
		#endif

		#ifdef ONLYGLOBAL
		case 3:
		{
			return(TRUE);
		}
		#endif
	}
	return(NULL);
}


Subject: Re: mcc ... [libnix libinit.c]
Date: 02 Jun 1996 13:56:31
References: <960528184901_101526.3324_IHK161-1@CompuServe.COM>
Organization: I&S Informatica e Servizi
X-Newsreader: MM v1.2x *UNREG*/NetGate 1.2a
Mime-Version: 1.0
Content-Transfer-Encoding: QUOTED-PRINTABLE
Resent-Message-Id: <"hzT633.0.yM1.xTWin"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1462
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 80
Status: RO
Content-Transfer-Encoding: QUOTED-PRINTABLE
Content-Type: TEXT/PLAIN; charset="ISO-8859-1"
Content-Length: 2644

Hello Willi,
in a message dated 28 May 96 you wrote to :

 W> The skeleton should only OpenLibrary() and of course CloseLibrary() the
 W> muimaster.library. since muimaster opens Dos, Utility, intuition [...]

You may need other libraries as well, for example Layers or Diskfont.

 W> To set up a4 is only necessary for baserelative code! Since the
 W> above mentioned Library bases are the only global variables in
 W> a MUI class, I think it is easier not to do it baserelative.

Well, in fact you can also have the library base pointers as members of
your own library base, so you don't really need *any* static data (except
constant data, maybe). You have to do something like this:

  struct MyLibBase
  {
    struct Library LibNode;
    ...

    struct MUI_CustomClass *my_Class;

    struct ExecBase *my_SysBase;
    struct Library  *my_MUIMasterBase;
    ...
  };

  #define SysBase       (my->my_SysBase)
  #define MUIMasterBase (my->my_MUIMasterBase)

This works for sure with SAS/C: of course you have to #include the pragmas
for all the libraries you need, but you should do it anyway...

The only drawback is: any of your functions that calls a library function
needs to get a pointer to your library base, and it has to be called "my".
But this is easy to do:

  VOID myFunction(, struct MyLibBase *my)
  {
    ...
  }

With callback hooks you could pass your library base in the h_Data field,
and retrieve it as the first thing you do:

  ASM VOID myHook(REG(a0) struct Hook *h,
    REG(a1) APTR msg, REG(a2) Object *obj)
  {
    struct MyLibBase *my =3D (struct MyLibBase *)h->h_Data;
    ...
  }

Since you will most probably have a pointer to your MUI custom class in the
library base as well, you could access the library base pointers in it with
another #define:

  #define UtilityBase (my->my_Class->mcc_UtilityBase)

It would be more efficient to have them directly in the library base,
though... You choose.

 W> To stick with the C source until we get a skeleton worked out [...]

I do have a skeleton based on MuiClassHeader.c (and I will incorporate any
intresting ideas found in the skeleton posted recently by Stefan -- I will
have a look at it today). Some small parts are in assembly, but that's
inavoidable if you want to be really sure about what pieces of code get
where; having everything in C is potentially dangerous, because no compiler
does guarantee where functions and/or data will go in the object file.

Ciao,
        Flavio

Subject: Re: custom class skeleton
To: mui@sunsite.Informatik.RWTH-Aachen.DE
Date: Mon, 3 Jun 1996 11:14:32 +0800 (WST)
In-Reply-To: <199606022127.XAA113632@venere.inet.it> from "Flavio Stanchina" at Jun 2, 96 02:19:12 pm
X-Mailer: ELM [version 2.4 PL25]
Mime-Version: 1.0
Content-Transfer-Encoding: 7bit
Resent-Message-Id: <"ouRTm2.0.jb2.fZbin"@sunsite>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.DE
Reply-To: mui@sunsite.Informatik.RWTH-Aachen.DE
X-Mailing-List:  archive/latest/1469
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.DE
X-Lines: 63
Status: RO
Content-Type: text/plain; charset="US-ASCII"
Content-Length: 2507

> not detailed enough. For example, I didn't find any information on what you
> can or cannot do in the MUIM_Draw method: it happens that I change rastport
> drawing pens and/or drawmode and some MUI objects get rendered incorrectly
> thereafter. Do I always have to clone the rastport?

I think you can do anything you like so long as you restore the
settings before the end of MUIM_Draw.
 
> Then, what about clipping? Do I have to do something special to install my
> own clip region(s)? I tried a simple InstallClipRegion(), and restored the
> original clip region as soon as I was done, but objects didn't graphically
> react to mouse actions any more.

Inside your MUIM_Draw method, have something along the lines of:

APTR clip = MUI_AddClipping(muiRenderInfo(obj), left, top, width,
height);

where (left, top) are the starting co-ordinates, and (0,0) is the top
left of the object's area. width is the width of the clipping region,
and height is its height.

When you have finished (again, still inside MUIM_Draw) you do:

MUI_RemoveClipping(muiRenderInfo(obj), clip);

Note that clip is the handle that was originally returned by
MUI_AddClipping(). That's it. You can nest clippings simply by calling
it again (with a different handle), MUI will take care of combining
them.

You can also use a struct ClipRegion. Here are Stefan's notes on the
subject:

APTR MUI_AddClipping      (struct MUI_RenderInfo *mri,WORD left,WORD top,WORD width,WORD height);
VOID MUI_RemoveClipping   (struct MUI_RenderInfo *mri,APTR handle);

and

APTR MUI_AddClipRegion    (struct MUI_RenderInfo *mri,struct Region *r);
VOID MUI_RemoveClipRegion (struct MUI_RenderInfo *mri,APTR handle);

do basically the same, once with coordinates and once with a struct Region.
Note that after MUI_AddClipRegion, you no longer need to worry about
freeing the structure, MUI_RemoveClipRegion will do this for you.

The MUI_AddXXX return a handle which must be passed to the MUI_RemoveXXX
function call. Adding clip regions cannot fail. You can nest clip regions,
MUI will automatically take care of that and "AND" new regions to existing
ones. Thus, the clipping calls work fine in virtual groups.
 
> Ciao,
>         Flavio

Cheers,
Jason.

Subject: Picture.mcc problem...
Date: 10 Jun 1996 18:34:30
Organization: primalinea & ESS software
X-Newsreader: MM v1.2x/p #1041/NetGate 1.2a
MIME-Version: 1.0
Content-Transfer-Encoding: QUOTED-PRINTABLE
Resent-Message-ID: <"h0tpq.0.nz2.vO7ln"@susi>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.de
X-Mailing-List:  archive/latest/1518
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.de
X-Lines: 215
Status: RO
Content-Type: TEXT/PLAIN; charset="ISO-8859-1"
Content-Length: 5435


HI!

I'm writing an external class that can show a picture.  This class use the
Datatypes.   The  class,  if MUI_PICTURE_Stretch is set to TRUE, scale the
image to fit in the area of the object.

I'm  using BitMapScale(bsa) function  to  do  this but when I try to run my
application  in  true  color and scale a 24bit colour bitmap, the function
fail.

In  256  color  mode  (or  less),  BitMapScale(bsa),  work (the picture is
scaled),  but  the  variable  "width"  in mNew(), is reset to -1 after the
call.

I'm using Cybergfx 2.18 and PDT v43.

Where I go wrong?

//Includes
//********
#include 
#include 
#include 
#include 

struct AlienImage
{	APTR obj;
	APTR bitmap;
};

struct Data
{
	char *File;
	BOOL Stretch;

	struct AlienImage *img;
#ifdef DEBUG
	BPTR	debug;
#endif
};


struct AlienImage *CaricaImmagine(struct MUI_RenderInfo *,char *);
void RilasciaImmagine(struct AlienImage *);

static ULONG mDraw(     struct IClass *cl,
                        Object *obj,
                        struct MUIP_Draw *msg)
{
   struct Data *data =3D INST_DATA(cl,obj);
	char pippo[200];
	ULONG width,height;
	ULONG bmpWidth,bmpHeight,bmpDepth;

   DoSuperMethodA(cl,obj,(Msg)msg);

   if (msg->flags & MADF_DRAWOBJECT)
   {	if (data->img) RilasciaImmagine(data->img);
		data->img=3DCaricaImmagine(muiRenderInfo(obj),"dati:disegni/primalin.gif"=
);
		if (!(data->img))
		{	DisplayBeep(0);
   	}
	}

	bmpWidth=3DGetBitMapAttr(data->img->bitmap,BMA_WIDTH);
	bmpHeight=3DGetBitMapAttr(data->img->bitmap,BMA_HEIGHT);
	bmpDepth=3DGetBitMapAttr(data->img->bitmap,BMA_DEPTH);

	if (data->Stretch)
	{	struct BitScaleArgs *bsa;
		struct BitMap *tmpBMP=3DNULL;
		=
		width=3D_mwidth(obj);									// Larghezza dell'oggetto
		height=3D_mheight(obj);								// Altezza dell'oggetto

#ifdef DEBUG
		sprintf(pippo,"%d %d %d\n",	bmpWidth,
												bmpHeight,
												bmpDepth);
		Write(data->debug,pippo,strlen(pippo));

		sprintf(pippo,"%d %d\n",		ScalerDiv(width,width,bmpWidth),
												ScalerDiv(height,height,bmpHeight));
		Write(data->debug,pippo,strlen(pippo));
#endif

		tmpBMP=3DAllocBitMap(  width,
									height,
									bmpDepth,
									BMF_INTERLEAVED|BMF_CLEAR,
									NULL);

		if (!tmpBMP)
		{	DisplayBeep(0);
			return(0);
		}

		bsa=3DAllocVec(sizeof (struct BitScaleArgs),MEMF_CLEAR);
		if (!bsa)
		{	DisplayBeep(0);DisplayBeep(0);
			FreeBitMap(tmpBMP);
			return(0);
		}

		bsa->bsa_SrcX=3D0;
		bsa->bsa_SrcY=3D0;
		bsa->bsa_SrcWidth=3D	bmpWidth;
		bsa->bsa_SrcHeight=3D	bmpHeight;
		bsa->bsa_XSrcFactor=3D	ScalerDiv(bmpWidth,width,bmpWidth);
		bsa->bsa_YSrcFactor=3D	ScalerDiv(bmpHeight,height,bmpHeight);
		bsa->bsa_DestX=3D0;
		bsa->bsa_DestY=3D0;
		bsa->bsa_DestWidth=3D0;
		bsa->bsa_DestHeight=3D0;
		bsa->bsa_XDestFactor=3DScalerDiv(width,width,bmpWidth);
		bsa->bsa_YDestFactor=3DScalerDiv(height,height,bmpHeight);
		bsa->bsa_SrcBitMap=3Ddata->img->bitmap;
		bsa->bsa_DestBitMap=3DtmpBMP;

		sprintf(pippo,"4:%d\n",width);
		Write(data->debug,pippo,strlen(pippo));

		BitMapScale(bsa);

		sprintf(pippo,"5:%d\n",width);
		Write(data->debug,pippo,strlen(pippo));

		BltBitMapRastPort(tmpBMP,
								0,
								0,
								_rp(obj),
								_mleft(obj),
								_mtop(obj),
								bsa->bsa_DestWidth,
								bsa->bsa_DestHeight,
								0x0c0);

		sprintf(pippo,"%d %d %d %d\n",	bsa->bsa_DestWidth,
													bsa->bsa_DestHeight,
													width,height);
		Write(data->debug,pippo,strlen(pippo));

		FreeVec(bsa);
		FreeBitMap(tmpBMP);
		return(0);
	}

	width=3DbmpWidth;
	if (width>(_mright(obj)-_mleft(obj))) width=3D_mright(obj)-_mleft(obj);
	height=3DbmpHeight;
	if (height>(_mbottom(obj)-_mtop(obj))) height=3D_mbottom(obj)-_mtop(obj);
	BltBitMapRastPort(	data->img->bitmap,
								0,
								0,
								_rp(obj),
								_mleft(obj),
								_mtop(obj),
								width,
								height,
								0x0c0
							);

   return(0);
}

struct AlienImage *CaricaImmagine(struct MUI_RenderInfo *mri,char *spec)
{
	struct AlienImage *img;
	APTR obj,bitmap;

	img=3DAllocVec(sizeof(struct AlienImage),MEMF_CLEAR);
	if (!img) return(NULL);

   {	obj =3D NewDTObject(spec,
								DTA_GroupID          , GID_PICTURE,
                        PDTA_FreeSourceBitMap, TRUE,
                        OBP_Precision        , PRECISION_EXACT,
                        PDTA_DestMode        , MODE_V43,
                        PDTA_UseFriendBitMap , TRUE,
                        PDTA_Screen          , mri->mri_Screen,
                        TAG_DONE);

      if (obj)
      {	struct FrameInfo fri =3D {NULL};
         DoMethod(obj,DTM_FRAMEBOX,NULL,&fri,&fri,sizeof(struct FrameInfo),=
0);
         if (fri.fri_Dimensions.Depth>0)
			{	if (DoMethod(obj,DTM_PROCLAYOUT,NULL,1))
            {	struct BitMapHeader *bmhd;
               get(obj,PDTA_BitMapHeader,&bmhd);
               GetDTAttrs(obj,PDTA_DestBitMap,&bitmap,TAG_DONE);
               if (!bitmap) GetDTAttrs(obj,PDTA_BitMap,&bitmap,TAG_DONE);
					img->bitmap=3Dbitmap;
					img->obj=3Dobj;
               return(img);
            }
         }
         DisposeDTObject(obj);
      }
	}
   return(NULL);
}

void RilasciaImmagine(struct AlienImage *img)
{
	DisposeDTObject(img->obj);
}

Serialmente BY(T)E!  Paolo.Menichetti@infoservice.it  2:332/118.13@fidonet
Paolo Menichetti     menichetti@nikita.nervous.com    39:102/201.13@amigane=
t

Subject: Betatesters for Picture.mcc wanted!
Date: 13 Jun 1996 16:51:08
Organization: primalinea & ESS software
X-Newsreader: MM v1.2x/p #1041/NetGate 1.2a
MIME-Version: 1.0
Content-Transfer-Encoding: QUOTED-PRINTABLE
Resent-Message-ID: <"uyuir.0.5b3.PR9mn"@susi>
Resent-From: mui@sunsite.Informatik.RWTH-Aachen.de
X-Mailing-List:  archive/latest/1544
X-Loop: mui@sunsite.informatik.rwth-aachen.de
Precedence: list
Resent-Sender: mui-request@sunsite.Informatik.RWTH-Aachen.de
X-Lines: 20
Status: RO
Content-Type: TEXT/PLAIN; charset="ISO-8859-1"
Content-Transfer-Encoding: QUOTED-PRINTABLE
Content-Length: 539


I'm looking for some betatesters of my picture.mcc class.  It allow load a
picture with datatype, scale it, and support CyberGFX.

I need someone that could test it on:
- ECS machines;
- AGA machines (with/out CyberGFX);
- CyberGFX machines.

A test application are included.

Picture.mcc require AmigaOS 3.x.

Please, e-mail me the request with a short descripion of your system.

Serialmente BY(T)E!  Paolo.Menichetti@infoservice.it  2:332/118.13@fidonet
Paolo Menichetti     menichetti@nikita.nervous.com    39:102/201.13@amigane=
t